package com.nervenets.template.controller.user.dto;

import com.nervenets.general.Global;
import com.nervenets.general.enumeration.ClientType;
import com.nervenets.general.enumeration.Platform;
import com.nervenets.general.exception.LogicException;
import com.nervenets.general.model.BaseModel;
import com.nervenets.general.model.SecurityUser;
import com.nervenets.general.service.GlobalSecurityService;
import com.nervenets.general.service.SnowFlakeService;
import com.nervenets.general.utils.HttpTools;
import com.nervenets.general.utils.JodaUtils;
import com.nervenets.general.utils.SnowFlakeIdentifierGenerator;
import com.nervenets.general.utils.SpringContextHolder;
import com.nervenets.general.web.params.EntityPagingParams;
import com.nervenets.template.enumeration.UserType;
import com.nervenets.template.hibernate.domain.user.RoleGroup;
import com.nervenets.template.hibernate.domain.user.User;
import com.nervenets.template.service.RoleGroupService;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.springframework.beans.BeanUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class TouristsLoginDto implements Serializable {
    @ApiModelProperty(value = "IP")
    private String ip;
    @ApiModelProperty(value = "密钥")
    private String token;

    public TouristsLoginDto(String license, GlobalSecurityService globalSecurityService, RoleGroupService roleGroupService, HttpServletRequest request) {
        this.ip = HttpTools.getIpAddress(request);
        String platformValue = request.getHeader(Global.Constants.PLATFORM_KEY);
        Platform platform = Platform.valueOf(platformValue);
        if (Platform.management.equals(platform)) {
            throw new LogicException("user platform not support.");
        }

        List<Long> roleGroupIds = roleGroupService.findAll(new EntityPagingParams<RoleGroup>() {
            @Override
            public void generateSpecification(List<Predicate> predicates, Root<RoleGroup> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                addEqualsPredicate(root.get("clientType"), ClientType.tourists);
                addEqualsPredicate(root.get("enable"), true);
            }
        }).stream().map(RoleGroup::getId).sorted().collect(Collectors.toList());

        SecurityUser securityUser = new SecurityUser(SpringContextHolder.getBean(SnowFlakeService.class).nextId(), this.ip, this.ip, ClientType.tourists);
        securityUser.setRoleIds(roleGroupIds);
        securityUser.addExtra("ip", HttpTools.getIpAddress(request));
        securityUser.addExtra("agent", request.getHeader("User-Agent"));
        securityUser.addExtra("userType", UserType.user.name());
        securityUser.addExtra("loginTime", JodaUtils.getTimestamp());
        securityUser.addExtra("platform", platformValue);

        this.token = globalSecurityService.getToken(securityUser, license);
    }
}
